package com.mongodb.service;

import com.mongodb.BasicDBObject;
import com.mongodb.constants.collection.AddressConstants;
import com.mongodb.dao.AddressDao;
import com.mongodb.document.test.AddressDocument;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.List;

import static org.springframework.data.mongodb.core.aggregation.Aggregation.group;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation;
import static org.springframework.data.mongodb.core.query.Criteria.where;

@Service
public class AddressService {
    @Autowired
    private AddressDao addressDao;
    @Autowired
    private MongoTemplate mongoTemplate;

    public List<AddressDocument> findAddressDocumentList() {
        return addressDao.findAddressDocument();
    }

    public void saveAddressDocument(AddressDocument document) {
        addressDao.save(document);
    }

    public AddressDocument findAddressDocument(String city, Integer pincode) {
        return mongoTemplate.findOne(new Query(where(AddressConstants.CITY).is(city)
                .and(AddressConstants.PINCODE).gte(pincode)), AddressDocument.class);
    }

    public List<BasicDBObject> findAddressDocumentByGroup() {
        GroupByResults<BasicDBObject> addressDocumentGroup = mongoTemplate.group(
                AddressConstants.COLLECT_NAME,
                GroupBy.key(AddressConstants.CITY, AddressConstants.PINCODE)
                        .initialDocument("{total:0}")
                        .reduceFunction("function(doc, prev){prev.total+=1}"),
                BasicDBObject.class);
        System.out.println(addressDocumentGroup.getCount());
        System.out.println(addressDocumentGroup.getKeys());
        System.out.println(addressDocumentGroup.getRawResults());
        System.out.println(addressDocumentGroup.getServerUsed());
        return Lists.newArrayList(addressDocumentGroup.iterator());
    }

    public List<BasicDBObject> findAgregate() {
        TypedAggregation<AddressDocument> agg = newAggregation(AddressDocument.class,
                group(AddressConstants.CITY).count().as("count"));
        return mongoTemplate.aggregate(agg, BasicDBObject.class).getMappedResults();
    }

}
